package cn.daniellee.plugin.rs.storage;

import cn.daniellee.plugin.rs.RestrictedShop;
import cn.daniellee.plugin.rs.model.PlayerData;
import com.google.gson.Gson;

import java.sql.*;

public class MysqlStorage extends Storage {

	private Connection connection;

	private final String tablePrefix = RestrictedShop.getInstance().getConfig().getString("storage.mysql.table-prefix", "rs_");

	@Override
	public boolean initialize() {
		// 初始化Mysql驱动
		try {
			Class.forName("com.mysql.jdbc.Driver");
		} catch (ClassNotFoundException e) {
			RestrictedShop.getInstance().getLogger().info(" ");
			RestrictedShop.getInstance().getLogger().info("[RestrictedShop]An error occurred while getting the Mysql database driver.");
			RestrictedShop.getInstance().getLogger().info(" ");
			e.printStackTrace();
			return false;
		}
		// 初始化连接
		String url = "jdbc:mysql://" + RestrictedShop.getInstance().getConfig().getString("storage.mysql.host", "localhost") + ":" + RestrictedShop.getInstance().getConfig().getInt("storage.mysql.port", 3306) + "/" + RestrictedShop.getInstance().getConfig().getString("storage.mysql.database", "minecraft") + "?" + RestrictedShop.getInstance().getConfig().getString("storage.mysql.parameter", "characterEncoding=utf-8&useSSL=false");
		try {
			connection = DriverManager.getConnection(url, RestrictedShop.getInstance().getConfig().getString("storage.mysql.username", "username"), RestrictedShop.getInstance().getConfig().getString("storage.mysql.password", "password"));
		} catch (SQLException e) {
			RestrictedShop.getInstance().getLogger().info(" ");
			RestrictedShop.getInstance().getLogger().info("[RestrictedShop]Mysql connection information is incorrect.".replace("&", "§"));
			RestrictedShop.getInstance().getLogger().info(" ");
			e.printStackTrace();
			return false;
		}
		// 初始化数据表
		String sql = "CREATE TABLE IF NOT EXISTS `" + tablePrefix + "player` (" +
				"`name` varchar(48) NOT NULL," +
				"`shop` varchar(32) NOT NULL," +
				"`check_sum` varchar(32) NOT NULL," +
				"`index_list` varchar(255)," +
				"`purchase_numbers` varchar(255)," +
				"`sold_numbers` varchar(255)," +
				"`percentage` int(5)," +
				"`generate_at` bigint(20)," +
				"UNIQUE KEY `PLAYER_UNIQUE` (`name`, `shop`)" +
				") ENGINE=InnoDB DEFAULT CHARSET=utf8;";
        try (Statement statement = connection.createStatement()) {
            statement.execute(sql);
        } catch (SQLException e) {
            RestrictedShop.getInstance().getLogger().info(" ");
            RestrictedShop.getInstance().getLogger().info("[RestrictedShop]An error occurred while initializing the Mysql data table.".replace("&", "§"));
            RestrictedShop.getInstance().getLogger().info(" ");
            e.printStackTrace();
            return false;
        }
		return true;
	}

	@Override
	public Connection getConnection() {
		return connection;
	}

	@Override
	public PlayerData getPlayerData(String name, String shop) {
		String sql = "SELECT `name`,`shop`,`check_sum`,`index_list`,`purchase_numbers`,`sold_numbers`,`percentage`,`generate_at` FROM `" + tablePrefix + "player` WHERE `name` = ? AND `shop` = ?";
		try (PreparedStatement statement = connection.prepareStatement(sql)) {
			statement.setString(1, name);
			statement.setString(2, shop);
			ResultSet resultSet = statement.executeQuery();
			if (resultSet.next()) {
				PlayerData playerData = new PlayerData();
				playerData.setName(resultSet.getString("name"));
				playerData.setShop(resultSet.getString("shop"));
				playerData.setCheckSum(resultSet.getString("check_sum"));
				playerData.setIndexList(new Gson().fromJson(resultSet.getString("index_list"), Integer[].class));
				playerData.setPurchaseNumbers(new Gson().fromJson(resultSet.getString("purchase_numbers"), Integer[].class));
				playerData.setSoldNumbers(new Gson().fromJson(resultSet.getString("sold_numbers"), Integer[].class));
				playerData.setPercentage(resultSet.getInt("percentage"));
				playerData.setGenerateAt(resultSet.getLong("generate_at"));
				return playerData;
			}
		} catch (SQLException e) {
			RestrictedShop.getInstance().getLogger().info(" ");
			RestrictedShop.getInstance().getLogger().info("[RestrictedShop]An error occurred while reading building data from Mysql.".replace("&", "§"));
			RestrictedShop.getInstance().getLogger().info(" ");
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public void savePlayerData(PlayerData playerData) {
		String sql = "INSERT INTO `" + tablePrefix + "player` (`name`,`shop`,`check_sum`,`index_list`,`purchase_numbers`,`sold_numbers`,`percentage`,`generate_at`) VALUES (?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE `check_sum` = ?,`index_list` = ?,`purchase_numbers` = ?,`sold_numbers` = ?,`percentage` = ?,`generate_at` = ?;";
		try (PreparedStatement statement = connection.prepareStatement(sql)) {
			statement.setString(1, playerData.getName());
			statement.setString(2, playerData.getShop());
			statement.setString(3, playerData.getCheckSum());
			String indexList = new Gson().toJson(playerData.getIndexList());
			statement.setString(4, indexList);
			String purchaseNumbers = new Gson().toJson(playerData.getPurchaseNumbers());
			statement.setString(5, purchaseNumbers);
			String soldNumbers = new Gson().toJson(playerData.getSoldNumbers());
			statement.setString(6, soldNumbers);
			statement.setInt(7, playerData.getPercentage());
			statement.setLong(8, playerData.getGenerateAt());
			statement.setString(9, playerData.getCheckSum());
			statement.setString(10, indexList);
			statement.setString(11, purchaseNumbers);
			statement.setString(12, soldNumbers);
			statement.setInt(13, playerData.getPercentage());
			statement.setLong(14, playerData.getGenerateAt());
			statement.executeUpdate();
		} catch (SQLException e) {
			RestrictedShop.getInstance().getLogger().info(" ");
			RestrictedShop.getInstance().getLogger().info("[RestrictedShop]An error occurred while reading building data from Mysql.".replace("&", "§"));
			RestrictedShop.getInstance().getLogger().info(" ");
			e.printStackTrace();
		}
	}

	@Override
	public void deletePlayerData(String name, String shop) {
		String sql = "DELETE FROM `" + tablePrefix + "player` WHERE `name` = ? AND `shop` = ?;";
		try (PreparedStatement statement = connection.prepareStatement(sql)) {
			statement.setString(1, name);
			statement.setString(2, shop);
			statement.execute();
		} catch (SQLException e) {
			RestrictedShop.getInstance().getLogger().info(" ");
			RestrictedShop.getInstance().getLogger().info("[RestrictedShop]An error occurred while reading building data from Mysql.".replace("&", "§"));
			RestrictedShop.getInstance().getLogger().info(" ");
			e.printStackTrace();
		}
	}

	public void close() {
		try {
			connection.close();
		} catch (SQLException ignored) { }
	}
}
